package com.xdtech.hotel.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.collect.Maps;
import com.thoughtworks.xstream.XStream;
import com.xdtech.common.utils.EmptyUtil;
import com.xdtech.core.dao.BaseDao;
import com.xdtech.core.model.BaseItem;
import com.xdtech.core.orm.Page;
import com.xdtech.core.orm.utils.BeanUtils;
import com.xdtech.hotel.dao.RoomDao;
import com.xdtech.hotel.model.Device;
import com.xdtech.hotel.model.DeviceLink;
import com.xdtech.hotel.model.Room;
import com.xdtech.hotel.model.RoomConfig;
import com.xdtech.hotel.protocol.manager.RoomMonitor;
import com.xdtech.hotel.service.DeviceLinkService;
import com.xdtech.hotel.service.DeviceService;
import com.xdtech.hotel.service.RoomConfigService;
import com.xdtech.hotel.service.RoomService;
import com.xdtech.hotel.vo.DeviceLinkItem;
import com.xdtech.hotel.vo.RoomConfigItem;
import com.xdtech.hotel.vo.RoomItem;
import com.xdtech.web.model.Pagination;

/**
 * 
 * @author max.zheng
 * @create 2015-04-01 22:53:23
 * @since 1.0
 * @see
 */
@Service
public class RoomServiceImpl implements RoomService {
	@Autowired
	private RoomDao roomDao;
	@Autowired
	private BaseDao baseDao;
	@Autowired
	private DeviceLinkService deviceLinkService;
	@Autowired
	private DeviceService deviceService;
	@Autowired
	private RoomConfigService roomConfigService;
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-04-01 22:53:23
	 * @modified by
	 * @param entity
	 */
	public void save(Room entity) {
		roomDao.save(entity);
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-04-01 22:53:23
	 * @modified by
	 * @param entity
	 */
	public void saveAll(List<Room> entities) {
		roomDao.saveAll(entities);
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-04-01 22:53:23
	 * @modified by
	 * @param entity
	 */
	public void delete(Room entity) {
		roomDao.delete(entity);
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-04-01 22:53:23
	 * @modified by
	 * @param id
	 */
	public void delete(Long id) {
		roomDao.delete(id);
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-04-01 22:53:23
	 * @modified by
	 * @param id
	 * @return
	 */
	public Room get(Long id) {
		return roomDao.get(id);
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-04-01 22:53:23
	 * @modified by
	 * @return
	 */
	public List<Room> getAll() {
		return roomDao.getAll();
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-04-01 22:53:23
	 * @modified by
	 * @param pg
	 * @param values
	 * @return
	 */
	public Map<String, Object> loadPageAndCondition(Pagination pg,
			Map<String, String> values) {
		Map<String, Object> results = new HashMap<String, Object>();
		List<Object> rooms = null;
		long rows = 0;
		if (pg!=null) {
			Page<Room> page = roomDao.findPage(pg,"from Room order by createTime desc", values);
			rooms = BeanUtils.copyListProperties(
					RoomItem.class, page.getResult());
			rows = page.getTotalItems();
		}else {
			List<Room> roomList = roomDao.find("from Room order by id desc", values);
			rooms = BeanUtils.copyListProperties(
					RoomItem.class, roomList);
			rows = rooms.size();
		}
		results.put("total", rows);
		results.put("rows", rooms);
		return results;
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-04-01 22:53:23
	 * @modified by
	 * @param item
	 * @return
	 */
	public boolean saveOrUpdateRoom(RoomItem item) {
		Room room = null;
		if (item.getId()==null) {
			room = new Room();
		}else {
			room = roomDao.get(item.getId());
			room.setConfigXmlInfo(new XStream().toXML(item));
		}
		if (StringUtils.isNotBlank(item.getDeviceId())) {
			room.setDevice(new Device(Long.valueOf(item.getDeviceId())));
		}
		BeanUtils.copyProperties(room, item);
		roomDao.save(room);
		return true;
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-04-01 22:53:23
	 * @modified by
	 * @param roomId
	 * @return
	 */
	public RoomItem loadRoomItem(Long roomId) {
		Room room = roomDao.get(roomId);
		return RoomItem.createItem(room);
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-04-01 22:53:23
	 * @modified by
	 * @param id
	 * @return
	 */
	public boolean deleteRoomInfo(long id) {
		delete(id);
		return true;
	}
	
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-04-01 22:53:23
	 * @modified by
	 * @param newIds
	 * @return
	 */
	public boolean deleteRoomInfo(List<Long> roomIds) {
		for (Long id : roomIds) {
			deleteWithCache(id);
		}
		return true;
	}
	
	
	/**
	 * 
	 * @author max.zheng
	 * @create 2015-4-11下午8:04:55
	 * @modified by
	 * @param id
	 */
	private void deleteWithCache(Long id) {
		Room room = roomDao.get(id);
//		if (room.getDevice()!=null) {
			RoomMonitor.removeRoom(room.getRoomNo());
//		}
		delete(room);
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-4-1下午10:54:48
	 * @modified by
	 * @return
	 */
	@Override
	public List<RoomItem> loadAllRoomItems() {
		return RoomItem.createItems(roomDao.getAll());
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-4-6上午10:34:39
	 * @modified by
	 * @param roomItem
	 */
	@Override
	public void saveRoomInfos(RoomItem roomItem) {
		Room room = null;
		if (roomItem.getId()==null) {
			room = new Room();
		}else {
			room = roomDao.get(roomItem.getId());
		}
		BeanUtils.copyProperties(room, roomItem);
//		room.setDevice(new Device(Long.valueOf(roomItem.getDeviceId())));
		Device device = deviceService.get(Long.valueOf(roomItem.getDeviceId()));
		roomItem.setDeviceName(device.getName());
		roomItem.setDeviceIp(device.getIp());
		roomItem.setDevicePort(device.getPort());
		roomItem.setDeviceSn(device.getSn());
		
		room.setConfigXmlInfo(new XStream().toXML(roomItem));
		room.setDevice(device);
		roomDao.save(room);
		roomItem.setId(room.getId());
		//监控更新
		RoomMonitor.updateMonitorRoomInfo(roomItem);
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-4-6上午11:03:56
	 * @modified by
	 * @param roomType
	 * @return
	 */
	@Override
	public Map<String, Object> loadRoomUnSelectDeviceLinks(String roomId) {
		List<DeviceLink> allDeviceLinks = deviceLinkService.getAll();
		List<DeviceLinkItem> unSelectDeviceLinkItems = new ArrayList<DeviceLinkItem>();
		if (StringUtils.isNotBlank(roomId)) {
			Room room = roomDao.get(Long.valueOf(roomId));
			if (room!=null&&StringUtils.isNotBlank(room.getConfigXmlInfo())) {
				for (DeviceLink deviceLink : allDeviceLinks) {
					if (room.getConfigInfo()!=null&&!room.getConfigInfo().contains(deviceLink.getLid())) {
						unSelectDeviceLinkItems.add(DeviceLinkItem.createItem(deviceLink));
					}
				}
			}else {
				unSelectDeviceLinkItems = DeviceLinkItem.createItems(allDeviceLinks);
			}
		}else {
			unSelectDeviceLinkItems = DeviceLinkItem.createItems(allDeviceLinks);
		}
		
		Map<String, Object> results = new HashMap<String, Object>();
		results.put("total", unSelectDeviceLinkItems.size());
		results.put("rows",  unSelectDeviceLinkItems);
		return results;
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-4-6上午11:03:56
	 * @modified by
	 * @param roomType
	 * @return
	 */
	@Override
	public Map<String, Object> loadRoomSelectDeviceLinks(String roomId) {
		int total = 0;
		List<?> rows = new ArrayList();
		Map<String, Object> results = new HashMap<String, Object>();
		if (StringUtils.isNotBlank(roomId)) {
			Room room = roomDao.get(Long.valueOf(roomId));
			if (room!=null&&StringUtils.isNotBlank(room.getConfigXmlInfo())) {
				XStream xstream = new XStream(); 
				RoomItem roomItem = (RoomItem) xstream.fromXML(room.getConfigXmlInfo());
				total = roomItem.getDeviceLinks().size();
				rows = roomItem.getDeviceLinks();
			}
		}
		results.put("total", total);
		results.put("rows",  rows);
		return results;
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-4-14下午10:03:26
	 * @modified by
	 * @param items
	 */
	@Override
	public String saveImportRoomInfos(List<RoomItem> items) {
		String rs = checkImportData(items);
		if (rs.length()>0) {
			return rs;
		}
		for (RoomItem roomItem : items) {
			Device device = new Device();
			device.setSn(roomItem.getDeviceSn());
			device.setIp(roomItem.getDeviceIp());
			device.setPort(roomItem.getDevicePort());
			device.setName(roomItem.getDeviceName());
			deviceService.save(device);
			
			Room room = new Room();
			BeanUtils.copyProperties(room, roomItem);
			//查看客房类型是否已配置模版信息
			RoomConfig roomConfig = roomConfigService.getRoomConfigByRoomType(0L,roomItem.getType());
			RoomConfigItem roomConfigItem =  (RoomConfigItem) new XStream().fromXML(roomConfig.getConfigXml());
			roomItem.setConfigInfo(roomConfigItem.getConfigInfo());
			roomItem.setDeviceLinks(roomConfigItem.getDeviceLinks());
			//设置结束
			room.setConfigXmlInfo(new XStream().toXML(roomItem));
			room.setDevice(device);
			save(room);
			RoomMonitor.updateMonitorRoomInfo(roomItem);
		}
		
		return "";
	}
	
	private String checkImportData(List<RoomItem> items) {
		StringBuffer sb = new StringBuffer("");
		for (RoomItem roomItem : items) {
			//检查房间号是否重复
			List roomList  = roomDao.findByHql("from Room where roomNo=?", roomItem.getRoomNo());
			if (EmptyUtil.isNotEmpty(roomList)) {
				sb.append("房间号"+roomItem.getRoomNo()+"已存在");
			}
			List<Device> devices = deviceService.checkDeviceInfo(roomItem.getDeviceName(),roomItem.getDeviceSn(),roomItem.getDeviceIp());
			if (EmptyUtil.isNotEmpty(devices)) {
				sb.append("设备信息："+roomItem.getDeviceName()+"、"+roomItem.getDeviceIp()+"、"+roomItem.getDevicePort()+",可能存在重复，请核查.\r\n");
			}
		}
		return sb.toString();
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-4-17下午9:39:06
	 * @modified by
	 * @param deviceIds
	 * @return
	 */
	@Override
	public List<Room> getRoomByDeviceIds(List<Long> deviceIds) {
		Map<String, Object> values = Maps.newHashMap();
		values.put("deviceIds", deviceIds);
		List<Room> rooms = roomDao.find("from Room where device.id in(:deviceIds)", values);
		return rooms;
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-4-18下午12:17:14
	 * @modified by
	 * @param pg
	 * @param baseItem
	 * @param queryName
	 * @return
	 */
	@Override
	public Map<String, Object> loadPageDataByConditions(Pagination pg,
			BaseItem baseItem, String queryName) {
		Map<String, Object> results = new HashMap<String, Object>();
		Page page = baseDao.findPageByNamedQuery(pg, queryName,baseItem);
		results.put("total", page.getTotalItems());
		results.put("rows", page.getResult());
		return results;
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-4-18下午10:00:35
	 * @modified by
	 * @param roomId
	 * @param status
	 */
	@Override
	public RoomItem roomUpdateStatus(Long roomId, String status,String customerName) {
		Room room = get(roomId);
		RoomItem roomItem = RoomItem.createItem(room);
		roomItem.setStatus(status);
		roomItem.setCustomer(customerName);
		room.setStatus(status);
		//监控更新
		RoomMonitor.updateMonitorRoomInfo(roomItem);
		//回填roomItem xml配置信息
		room.setConfigXmlInfo(new XStream().toXML(roomItem));
		roomDao.save(room);
		return roomItem;
	}
	/* (非 Javadoc)
	 * loadRoomItemBySn
	 * <p>对override方法的补充说明，若不需要则删除此行</p>
	 * 
	 * @param sn
	 * @return
	 * @see com.xdtech.hotel.service.RoomService#loadRoomItemBySn(java.lang.String)
	 */
	@Override
	public RoomItem loadRoomItemBySn(String sn)
	{
		Room room = (Room) roomDao.findUnique("from Room where device.sn=?", sn);
		RoomItem roomItem = RoomItem.createItem(room);
		return roomItem;
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-5-23下午7:15:45
	 * @modified by
	 * @param id
	 * @param roomNo
	 * @return
	 */
	@Override
	public boolean checkIsExsit(Long id, String roomNo) {
		if(id==null) id = -1L;
		List<Room> rooms = roomDao.findByHql("from Room where id!=? and roomNo=?", id,roomNo);
		return rooms.size()>0;
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-5-23下午7:59:27
	 * @modified by
	 * @param valueOf
	 * @param roomDeviceName
	 * @return
	 */
	@Override
	public boolean checkRcuIsExit(Long id, String roomDeviceName) {
		List<Room> rooms = roomDao.findByHql("from Room where id!=? and device.name=?", id,roomDeviceName);
		return rooms.size()>0;
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-6-23下午9:21:11
	 * @modified by
	 * @param cardId
	 * @return
	 */
	@Override
	public List<RoomItem> loadNotCardRooms(Long cardId) {
		List<Room> rooms = roomDao.findByHql("from Room where id not in(select roomId from CardToRoom where cardId=?)", cardId);
		return RoomItem.createItems(rooms);
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-6-23下午9:21:11
	 * @modified by
	 * @param cardId
	 * @return
	 */
	@Override
	public List<RoomItem> loadUserRoles(Long cardId) {
		List<Room> rooms = roomDao.findByHql("from Room where id in(select roomId from CardToRoom where cardId=?)", cardId);
		return RoomItem.createItems(rooms);
	}
	


}
